# Copyright 2024 The Pigweed Authors
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may not
# use this file except in compliance with the License. You may obtain a copy of
# the License at
#
#     https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations under
# the License.

load("@rules_cc//cc:cc_library.bzl", "cc_library")
load("@rules_python//sphinxdocs:sphinx_docs_library.bzl", "sphinx_docs_library")
load("//pw_build:compatibility.bzl", "incompatible_with_mcu")
load("//pw_unit_test:pw_cc_test.bzl", "pw_cc_test")

package(default_visibility = ["//visibility:public"])

licenses(["notice"])

cc_library(
    name = "config",
    hdrs = ["public/pw_assert_trap/config.h"],
    strip_include_prefix = "public",
)

cc_library(
    name = "handler",
    hdrs = [
        "public/pw_assert_trap/handler.h",
    ],
    strip_include_prefix = "public",
    deps = [
        "//pw_preprocessor",
    ],
)

cc_library(
    name = "message",
    hdrs = [
        "public/pw_assert_trap/message.h",
    ],
    strip_include_prefix = "public",
    deps = [
        "//pw_string:string",
    ],
)

cc_library(
    name = "impl",
    srcs = [
        "trap_handler.cc",
    ],
    copts = ["-Wno-thread-safety-analysis"],
    deps = [
        ":config",
        ":handler",
        ":message",
        "//pw_string:builder",
        "//pw_sync:interrupt_spin_lock",
    ],
    # Other libraries may not always depend on this library, even if it is
    # necessary at link time.
    alwayslink = 1,
)

cc_library(
    name = "assert_backend",
    hdrs = [
        "assert_public_overrides/pw_assert_backend/assert_backend.h",
    ],
    strip_include_prefix = "assert_public_overrides",
    deps = [
        ":assert_backend_private",
    ],
)

cc_library(
    name = "assert_backend_private",
    hdrs = [
        "public/pw_assert_trap/assert_trap.h",
    ],
    strip_include_prefix = "public",
    visibility = ["//visibility:private"],
    deps = [
        ":handler",
    ],
)

cc_library(
    name = "check_backend",
    hdrs = [
        "check_public_overrides/pw_assert_backend/check_backend.h",
    ],
    strip_include_prefix = "check_public_overrides",
    deps = [
        ":check_backend_private",
    ],
)

cc_library(
    name = "check_backend_private",
    hdrs = [
        "public/pw_assert_trap/check_trap.h",
    ],
    strip_include_prefix = "public",
    visibility = ["//visibility:private"],
    deps = [
        ":handler",
    ],
)

# provide a test implementation which is compiled with a different set of
# defines to allow unittesting.
cc_library(
    name = "impl_test",
    srcs = [
        "trap_handler.cc",
    ],
    copts = ["-Wno-thread-safety-analysis"],
    defines = [
        # Disable the trap to allow testing to continue
        "_PW_ASSERT_TRAP_DISABLE_TRAP_FOR_TESTING=1",
        # Disable the capture of location info to ensure tests are portable
        "PW_ASSERT_TRAP_DISABLE_LOCATION_CAPTURE=1",
    ],
    visibility = ["//visibility:private"],
    deps = [
        ":config",
        ":handler",
        ":message",
        "//pw_string:builder",
        "//pw_sync:interrupt_spin_lock",
    ],
)

pw_cc_test(
    name = "handler_test",
    srcs = [
        "trap_handler_test.cc",
    ],
    # TODO: https://pwbug.dev/351889230 - this test will fail to build on any
    # platform that sets the pw_assert backend to //pw_assert_trap. To be safe,
    # disable it for any MCU platform. But run it on the host, where the assert
    # backend is pw_assert_basic.
    target_compatible_with = incompatible_with_mcu(),
    deps = [
        ":check_backend_private",
        ":impl_test",
        ":message",
    ],
)

sphinx_docs_library(
    name = "docs",
    srcs = [
        "docs.rst",
    ],
    prefix = "pw_assert_trap/",
    target_compatible_with = incompatible_with_mcu(),
)
